home *** CD-ROM | disk | FTP | other *** search
- #define NOTIMEZONE
-
- #ifndef lint
- static char *RCSid="$Id: strftime.c,v 1.4 1995/12/07 21:41:12 drd Exp $";
- #endif
-
- /*
- * Implementation of strftime for systems missing this (e.g. vaxctrl)
- *
- * This code was written based on the NeXT strftime man-page, sample output of
- * the function and an ANSI-C quickreference chart. This code does not use
- * parts of any existing strftime implementation.
- *
- * Apparently not all format chars are implemented, but this was all I had in
- * my documentation.
- *
- * (written by Alexander Lehmann)
- */
-
- #include <time.h>
- #include <string.h>
- #include <stdio.h>
- #include "setshow.h" /* for days/months */
-
- #ifdef TEST /* test case */
- #define strftime _strftime
- #else
- #define const /**/
- #endif
-
-
- static void fill(from, pto, pmaxsize)
- char *from;
- char **pto;
- size_t *pmaxsize;
- {
- strncpy(*pto, from, *pmaxsize);
- if(*pmaxsize<strlen(from)) {
- (*pto)+=*pmaxsize;
- *pmaxsize=0;
- } else {
- (*pto)+=strlen(from);
- (*pmaxsize)-=strlen(from);
- }
- }
-
- static void number(num, pad, pto, pmaxsize)
- int num;
- int pad;
- char **pto;
- size_t *pmaxsize;
- {
- char str[100];
-
- sprintf(str, "%0*d", pad, num);
- fill(str, pto, pmaxsize);
- }
-
- size_t strftime(s, max, format, tp)
- char *s;
- size_t max;
- const char *format;
- const struct tm *tp;
- {
- char *start=s;
- size_t maxsize=max;
-
- if(max>0) {
- while(*format && max>0) {
- if(*format!='%') {
- *s++=*format++;
- max--;
- } else {
- format++;
- switch(*format++) {
- case 'a': /* abbreviated weekday name */
- if(tp->tm_wday>=0 && tp->tm_wday<=6)
- fill(abbrev_day_names[tp->tm_wday], &s, &max);
- break;
- case 'A': /* full name of the weekday */
- if(tp->tm_wday>=0 && tp->tm_wday<=6)
- fill(full_day_names[tp->tm_wday], &s, &max);
- break;
- case 'b': /* abbreviated month name */
- if(tp->tm_mon>=0 && tp->tm_mon<=11)
- fill(abbrev_month_names[tp->tm_mon], &s, &max);
- break;
- case 'B': /* full name of month */
- if(tp->tm_mon>=0 && tp->tm_mon<=11)
- fill(full_month_names[tp->tm_mon], &s, &max);
- break;
- case 'c': /* locale's date and time reprensentation */
- strftime(s, max, "%a %b %X %Y", tp);
- max-=strlen(s);
- s+=strlen(s);
- break;
- case 'd': /* day of the month (01-31) */
- number(tp->tm_mday, 2, &s, &max);
- break;
- case 'H': /* hour of the day (00-23) */
- number(tp->tm_hour, 2, &s, &max);
- break;
- case 'I': /* hour of the day (01-12) */
- number((tp->tm_hour+11)%12+1, 2, &s, &max);
- break;
- case 'j': /* day of the year (001-366) */
- number(tp->tm_yday+1, 3, &s, &max);
- break;
- case 'm': /* month of the year (01-12) */
- number(tp->tm_mon+1, 2,&s, &max);
- break;
- case 'M': /* minute (00-59) */
- number(tp->tm_min, 2, &s, &max);
- break;
- case 'p': /* locale's version of AM or PM */
- fill(tp->tm_hour>=6 ? "PM" : "AM", &s, &max);
- break;
- case 'S': /* seconds (00-59) */
- number(tp->tm_sec, 2, &s, &max);
- break;
- case 'U': /* week number of the year (00-53) with Sunday as the first day of the week */
- number((tp->tm_yday-(tp->tm_yday-tp->tm_wday+7)%7+7)/7, 1, &s, &max);
- break;
- case 'w': /* weekday (Sunday=0 to Saturday=6) */
- number(tp->tm_wday, 1, &s, &max);
- break;
- case 'W': /* week number of the year (00-53) with Monday as the first day of the week */
- number((tp->tm_yday-(tp->tm_yday-tp->tm_wday+8)%7+7)/7, 2, &s, &max);
- break;
- case 'x': /* locale's date representation */
- strftime(s, max, "%a %b %d %Y", tp);
- max-=strlen(s);
- s+=strlen(s);
- break;
- case 'X': /* locale's time representation */
- #ifndef NOTIMEZONE
- strftime(s, max, "%H:%M:%S %Z", tp);
- #else
- strftime(s, max, "%H:%M:%S", tp);
- #endif
- max-=strlen(s);
- s+=strlen(s);
- break;
- case 'y': /* two-digit year representation (00-99) */
- number(tp->tm_year%100, 2, &s, &max);
- break;
- case 'Y': /* four-digit year representation */
- number(tp->tm_year+1900, 2, &s, &max);
- break;
- #ifndef NOTIMEZONE
- case 'Z': /* time zone name */
- fill(tp->tm_zone, &s, &max);
- break;
- #endif
- case '%': /* percent sign */
- default:
- *s++=*(format-1);
- max--;
- break;
- }
- }
- }
- if(s-start<maxsize) {
- *s++='\0';
- } else {
- *(s-1)='\0';
- }
- }
-
- return s-start;
- }
-
- #ifdef TEST
-
- #undef strftime
- #define test(s) \
- printf("%s -> ",s ); \
- _strftime(str, 100, s, ts); \
- printf("%s - ", str); \
- strftime(str, 100, s, ts); \
- printf("%s\n", str)
-
- int main()
- {
- char str[100];
- struct tm *ts;
- time_t t;
- int i;
-
- t=time(NULL);
-
- ts=localtime(&t);
-
- test("%c");
- test("test%%test");
- test("%a %b %d %X %Y");
- test("%x %X");
- test("%A %B %U");
- test("%I:%M %p %j %w");
-
- t-=245*24*60*60;
-
- for(i=0;i<366;i++) {
- ts=localtime(&t);
- printf("%03d: ", i);
- test("%a %d %m %W");
- t+=24*60*60;
- }
-
- return 0;
- }
-
- #endif
-
-